package com.eshipenet.shipnet.shiprpc.service;

import com.eshipenet.shipnet.ship.FindAllResult;
import com.eshipenet.shipnet.ship.Page;
import com.eshipenet.shipnet.ship.Query;
import com.eshipenet.shipnet.ship.Ship;
import com.eshipenet.shipnet.ship.grpc.ShipEdge;
import com.eshipenet.shipnet.shiprpc.util.BuilderUtil;
import com.eshipenet.shipnet.shiprpc.util.FormatSql;
import com.eshipenet.shipnet.shiprpc.util.PageUtil;
import org.apache.ignite.IgniteCache;
import org.apache.ignite.cache.query.FieldsQueryCursor;
import org.apache.ignite.cache.query.QueryCursor;
import org.apache.ignite.cache.query.SqlFieldsQuery;
import org.apache.ignite.cache.query.SqlQuery;
import org.apache.ignite.services.ServiceContext;
import org.json4s.JsonAST;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import scala.Option;
import squirrel.JSONQuery;

import javax.cache.Cache;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

public class ShipServiceImp implements ShipService {
    private Logger logger = LoggerFactory.getLogger("ShipServiceImp");
    private IgniteCache<String, Ship> cache ;

    public ShipServiceImp(IgniteCache<String, Ship> cache) {
        this.cache = cache;
    }

    @Override
    public FindAllResult findAll(JSONQuery jsonQuery, int limit, int offset) {
        Query query = FormatSql.getFormatSql(jsonQuery);
        SqlQuery<String, Ship> sql = new SqlQuery<>(Ship.class, query.getSql());
        sql.setArgs(FormatSql.sqlValueToObject(query.getWhere()));
        logger.info("query Ship list sql  {}",sql);
        QueryCursor<Cache.Entry<String, Ship>> cursor = cache.query(sql);
        Iterator<Cache.Entry<String, Ship>> iterator = cursor.iterator();

        List<ShipEdge> list = new ArrayList<>();
        //查询数量
        JSONQuery countJsonQuery = JSONQuery.apply(jsonQuery.from(),
                jsonQuery.where(),
                Option.apply(new JsonAST.JString("count(*) as count")),
                jsonQuery.includes(),
                jsonQuery.offset(),
                jsonQuery.limit());

        Query countQuery = FormatSql.getFormatSql(countJsonQuery);
        SqlFieldsQuery sqlFieldsQuery = new SqlFieldsQuery(countQuery.getSql());
        sqlFieldsQuery.setArgs(FormatSql.sqlValueToObject(countQuery.getWhere()));
        logger.info("query Ship count sql  {}",sqlFieldsQuery);
        int totalCount = 0;
        try (FieldsQueryCursor<List<?>> cursor1 = cache.query(sqlFieldsQuery)) {
            for (List<?> row : cursor1) {
                totalCount = Integer.parseInt(row.get(0).toString());
            }

        }

        if(totalCount<1){
            return  new FindAllResult<>(list,totalCount,null,null,false,false);

        }

        //分页工具
        Page page = PageUtil.page(limit, totalCount, offset);
        //起点数据
        int start = page.getStartIndex();
        //结点数据
        int end = page.getEndIndex();
        //计数器
        int times = 0;

        while (iterator.hasNext()) {
            Cache.Entry<String, Ship> p = iterator.next();
            if (p != null) {

                if (list.size() < limit) {
                    if (times >= start && times < end) {
                        ShipEdge ShipEdge = BuilderUtil.shipEdgeBuilder(p);
                        list.add(ShipEdge);
                    }
                } else {
                    break;
                }
            }
            times++;
        }

        return  new FindAllResult<>(list,
                totalCount,
                list.get(0).getCursor(),
                list.get(list.size()-1).getCursor(),
                page.isHasNextPage(),
                page.isHasPreviousPage());
    }

    @Override
    public Ship createOne(Ship ship) {

        cache.put(ship.getId(),ship);

        ship = cache.get(ship.getId());

        return ship;
    }

    @Override
    public Ship updateOne(String id, Ship ship) {
        Ship old = cache.get(id);

        ship = new Ship(
                ship.getMmsi(),
                ship.getName(),
                ship.getDescription(),
                ship.getAvatar(),
                ship.getInfo(),
                ship.getOwnerId(),
                old.getCreatedAt(),
                ship.getUpdatedAt(),
                id
        );


        cache.put(id, ship);

        return ship;
    }

    @Override
    public Ship deleteOne(String id) {
        Ship old = cache.get(id);
        Ship ship = new Ship(
                old.getMmsi(),
                old.getName(),
                old.getDescription(),
                old.getAvatar(),
                old.getInfo(),
                old.getOwnerId(),
                old.getCreatedAt(),
                old.getUpdatedAt(),
                id
        );

        SqlFieldsQuery query = new SqlFieldsQuery("delete from  Ship  where id=? ");
        cache.query(query.setArgs(id)).getAll();
        logger.info("delete Ship by id  sql  {}",query);
        return ship;
    }

    @Override
    public int getShipCountById(String id) {
        //查询数据总数
        SqlFieldsQuery query = new SqlFieldsQuery("select count(id) from  Ship where id=? ");

        query.setArgs(id);
        logger.info("query Ship count  by id  sql  {}",query);
        //数据总数
        java.util.List<?> getCount = cache.query(query).getAll().get(0);
        Object obj = getCount.get(0);

        int count = Integer.parseInt(obj.toString());

        return count;
    }

    @Override
    public void cancel(ServiceContext ctx) {

    }

    @Override
    public void init(ServiceContext ctx) throws Exception {

    }

    @Override
    public void execute(ServiceContext ctx) throws Exception {

    }
}
